package com.huaxonline.sign.sdk;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 签名SDK使用示例
 * 
 * @author zhaoshulei
 * @since 2023/9/13
 */
public class SignExample {
    
    public static void main(String[] args) {
        // 示例1: 基本使用
        basicExample();
        
        // 示例2: 使用不同算法
        algorithmExample();
        
        // 示例3: 发送HTTP请求
        httpRequestExample();
        
        // 示例4: 快速签名
        quickSignExample();
        
        // 示例5: 错误处理
        errorHandlingExample();
    }
    
    /**
     * 基本使用示例
     */
    public static void basicExample() {
        System.out.println("=== 基本使用示例 ===");
        
        String appId = "test_app";
        String secret = "test_secret_123456";
        
        // 创建签名客户端
        SignClient client = new SignClient(appId, secret);
        
        // 生成签名参数
        SignClient.SignParams signParams = client.generateSignParams();
        System.out.println("AppId: " + signParams.getAppId());
        System.out.println("Timestamp: " + signParams.getTimestamp());
        System.out.println("Nonce: " + signParams.getNonce());
        
        // 构建参数
        Map<String, Object> params = new HashMap<>();
        params.put("name", "张三");
        params.put("age", 25);
        params.put(SignClient.HEADER_TIMESTAMP, signParams.getTimestamp());
        params.put(SignClient.HEADER_NONCE, signParams.getNonce());
        
        // 生成签名
        String signature = client.generateSign(params);
        System.out.println("签名: " + signature);
        
        // 验证时间戳
        boolean isValid = client.isValidTimestamp(signParams.getTimestamp());
        System.out.println("时间戳有效: " + isValid);
    }
    
    /**
     * 不同算法示例
     */
    public static void algorithmExample() {
        System.out.println("\n=== 不同算法示例 ===");
        
        String appId = "test_app";
        String secret = "test_secret_123456";
        String data = "test_data";
        
        // SHA256算法
        SignClient sha256Client = new SignClient(appId, secret, SignClient.SignAlgorithm.SHA256);
        Map<String, Object> params = SignUtil.createParamsWithTimestamp();
        String sha256Sign = sha256Client.generateSign(params);
        System.out.println("SHA256签名: " + sha256Sign);
        
        // MD5算法
        SignClient md5Client = new SignClient(appId, secret, SignClient.SignAlgorithm.MD5);
        String md5Sign = md5Client.generateSign(params);
        System.out.println("MD5签名: " + md5Sign);
        
        // HMAC-SHA256算法
        SignClient hmacClient = new SignClient(appId, secret, SignClient.SignAlgorithm.HMAC_SHA256);
        String hmacSign = hmacClient.generateSign(params);
        System.out.println("HMAC-SHA256签名: " + hmacSign);
    }
    
    /**
     * HTTP请求示例
     */
    public static void httpRequestExample() {
        System.out.println("\n=== HTTP请求示例 ===");
        
        String appId = "test_app";
        String secret = "test_secret_123456";
        
        // 创建客户端（启用调试模式）
        SignClient client = new SignClient(appId, secret, SignClient.SignAlgorithm.SHA256, 900000L, true);
        
        // 示例1: 查询用户信息
        Map<String, Object> queryParams = new HashMap<>();
        queryParams.put("userId", "12345");
        
        try {
            SignClient.HttpResponse response = client.sendGet("http://localhost:8080/api/user/info", queryParams);
            System.out.println("查询用户信息响应: " + response.getStatusCode() + " - " + response.getBody());
        } catch (IOException e) {
            System.out.println("查询用户信息失败: " + e.getMessage());
        }
        
        // 示例2: 创建订单
        Map<String, Object> orderData = new HashMap<>();
        orderData.put("productId", "PROD001");
        orderData.put("quantity", 2);
        orderData.put("price", 99.99);
        
        try {
            SignClient.HttpResponse response = client.sendPostJson("http://localhost:8080/api/order/create", orderData);
            System.out.println("创建订单响应: " + response.getStatusCode() + " - " + response.getBody());
        } catch (IOException e) {
            System.out.println("创建订单失败: " + e.getMessage());
        }
        
        // 示例3: 上传文件
        Map<String, Object> uploadParams = new HashMap<>();
        uploadParams.put("fileName", "test.txt");
        uploadParams.put("fileSize", 1024);
        
        String fileContent = "这是测试文件内容";
        
        try {
            SignClient.HttpResponse response = client.sendPost("http://localhost:8080/api/file/upload", uploadParams, fileContent);
            System.out.println("上传文件响应: " + response.getStatusCode() + " - " + response.getBody());
        } catch (IOException e) {
            System.out.println("上传文件失败: " + e.getMessage());
        }
    }
    
    /**
     * 快速签名示例
     */
    public static void quickSignExample() {
        System.out.println("\n=== 快速签名示例 ===");
        
        String appId = "test_app";
        String secret = "test_secret_123456";
        
        // 构建参数
        Map<String, Object> params = new HashMap<>();
        params.put("orderId", "ORDER123456");
        params.put("amount", 100.50);
        
        // 快速生成签名
        String signature = SignUtil.quickSign(appId, secret, params);
        System.out.println("快速签名: " + signature);
        
        // 快速生成签名（包含请求体）
        String jsonBody = "{\"productId\":\"PROD001\",\"quantity\":2}";
        String signatureWithBody = SignUtil.quickSignWithBody(appId, secret, params, jsonBody);
        System.out.println("包含请求体的签名: " + signatureWithBody);
        
        // 使用工具类创建参数
        Map<String, Object> params2 = SignUtil.createParamsWithTimestamp();
        SignUtil.addParam(params2, "userId", "12345");
        SignUtil.addParam(params2, "action", "query");
        
        String signature2 = SignUtil.quickSign(appId, secret, params2);
        System.out.println("工具类创建的签名: " + signature2);
    }
    
    /**
     * 错误处理示例
     */
    public static void errorHandlingExample() {
        System.out.println("\n=== 错误处理示例 ===");
        
        // 示例1: 参数验证
        try {
            SignClient client = new SignClient("", "secret"); // 空的AppId
        } catch (IllegalArgumentException e) {
            System.out.println("参数验证错误: " + e.getMessage());
        }
        
        try {
            SignClient client = new SignClient("appId", ""); // 空的Secret
        } catch (IllegalArgumentException e) {
            System.out.println("参数验证错误: " + e.getMessage());
        }
        
        // 示例2: 网络请求错误处理
        String appId = "test_app";
        String secret = "test_secret_123456";
        SignClient client = new SignClient(appId, secret);
        
        Map<String, Object> params = new HashMap<>();
        params.put("test", "value");
        
        try {
            SignClient.HttpResponse response = client.sendGet("http://invalid-url:9999/api/test", params);
            if (response.isSuccess()) {
                System.out.println("请求成功: " + response.getBody());
            } else {
                System.out.println("请求失败: " + response.getStatusCode() + " - " + response.getBody());
            }
        } catch (IOException e) {
            System.out.println("网络请求异常: " + e.getMessage());
        }
        
        // 示例3: 时间戳验证
        long oldTimestamp = System.currentTimeMillis() - 2000000; // 2小时前
        boolean isValid = client.isValidTimestamp(oldTimestamp);
        System.out.println("旧时间戳有效: " + isValid);
        
        long currentTimestamp = System.currentTimeMillis();
        boolean isValid2 = client.isValidTimestamp(currentTimestamp);
        System.out.println("当前时间戳有效: " + isValid2);
    }
    
    /**
     * 高级用法示例
     */
    public static void advancedExample() {
        System.out.println("\n=== 高级用法示例 ===");
        
        String appId = "test_app";
        String secret = "test_secret_123456";
        
        // 创建自定义配置的客户端
        SignClient client = new SignClient(
            appId, 
            secret, 
            SignClient.SignAlgorithm.HMAC_SHA256, 
            1800000L, // 30分钟时间容差
            true      // 启用调试模式
        );
        
        // 构建复杂参数
        Map<String, Object> params = SignUtil.createParamsWithTimestamp();
        SignUtil.addParam(params, "userId", "12345");
        SignUtil.addParam(params, "action", "create");
        SignUtil.addParam(params, "data", "complex_data");
        
        // 生成签名
        String signature = client.generateSign(params);
        System.out.println("复杂参数签名: " + signature);
        
        // 验证签名参数
        boolean isValid = SignUtil.validateSignParams(params);
        System.out.println("签名参数有效: " + isValid);
        
        // 提取签名参数
        SignClient.SignParams signParams = SignUtil.extractSignParams(params);
        System.out.println("提取的签名参数: " + signParams.getAppId() + " - " + signParams.getTimestamp());
        
        // 移除签名参数
        Map<String, Object> cleanParams = SignUtil.removeSignParams(params);
        System.out.println("清理后的参数: " + cleanParams);
        
        // 安全获取参数
        String userId = SignUtil.getStringParam(params, "userId", "unknown");
        Integer age = SignUtil.getIntParam(params, "age", 0);
        System.out.println("安全获取参数 - userId: " + userId + ", age: " + age);
    }
}